package com.atguigu.gmall.product.service.impl;

import com.atguigu.gmall.product.service.TestService;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.sql.Time;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 *  上锁
 */
@Service
public class TestServiceImpl implements TestService {

    @Autowired
    private RedisTemplate redisTemplate;


    //上锁
    @Override
    public synchronized void testLock() {

        Integer num = (Integer) redisTemplate.opsForValue().get("num");
        //Long 特殊类型   Object --> Integer --> Long   同类型转换
        num++;
        redisTemplate.opsForValue().set("num",num);

    }


    @Autowired
    private RedissonClient redissonClient;


    @Override
    public void testLockMethod() {
         // apache  ab 压力测试  5000个请求
        //分布式锁
        RLock lock = redissonClient.getLock("testLockMethod:lock");
        try {
            boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
            if(res){
                Integer num = (Integer) redisTemplate.opsForValue().get("num");
                //Long 特殊类型   Object --> Integer --> Long   同类型转换
                num++;
                redisTemplate.opsForValue().set("num", num);
            }else{
                throw new RuntimeException("无票");// 1
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }



    }

    //读锁 上锁
    @Override
    public String testRead() {

        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWriteLock");
        readWriteLock.readLock().lock(10,TimeUnit.SECONDS);
        String msg = (String) redisTemplate.opsForValue().get("msg");

        return msg;
    }

    //写
    @Override
    public String testWrite() {

        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWriteLock");
        readWriteLock.writeLock().lock(10,TimeUnit.SECONDS);
        redisTemplate.opsForValue().set("msg","测试写操作");
        String msg = (String) redisTemplate.opsForValue().get("msg");
        return msg;
    }
    //测试分布式锁
//    @Override
//    public void testLockMethod() {
//        // 注意事项： 防止自己把别人的锁给解除了
////        String uuid = UUID.randomUUID().toString();
////        //0: 上锁   setnx
////        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid,3
////        ,TimeUnit.SECONDS);// 0 ：false 1:true
//        RLock lock = redissonClient.getLock("testLockMethod:lock");
//        lock.lock(3,TimeUnit.SECONDS);//100ms  商品详情页面  5部分 浏览器 200+ms  //局部设置过期时间
//        //获取到锁 上锁
//        Integer num = (Integer) redisTemplate.opsForValue().get("num");
//        //Long 特殊类型   Object --> Integer --> Long   同类型转换
//        num++;
//        redisTemplate.opsForValue().set("num", num);
//       // String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
//        //this.redisTemplate.execute(new DefaultRedisScript<>(script), Arrays.asList("lock"), Arrays.asList(uuid));
//        lock.unlock();
//
//    }
}
